﻿namespace Beetle
{
    using System;
    using System.Net;

    public abstract class ServerBase : IDisposable
    {
        private TcpServer _field_a;
        private bool _field_b;

        protected ServerBase()
        {
        }

        public void Dispose()
        {
            lock (this)
            {
                if (!this._field_b)
                {
                    this._field_b = true;
                    if (this._field_a != null)
                    {
                        this._field_a.Dispose();
                        this._field_a = null;
                    }
                }
            }
        }

        protected virtual void OnBindEvent(TcpServer server)
        {
            server.ChannelConnected += new EventChannelConnected(this.OnConnected);
            server.ChannelDisposed += new EventChannelDisposed(this.OnDisposed);
            server.ChannelCreating += new EventChannglCreating(this.OnCreatingChannel);
        }

        protected virtual void OnConnected(object sender, ChannelEventArgs e)
        {
            e.Channel.DataReceive = new EventDataReceive(this.OnReceive);
            e.Channel.ChannelError += new EventChannelError(this.OnError);
            e.Channel.BeginReceive();
        }

        protected virtual void OnCreatingChannel(object sender, ChannelCreatingArgs e)
        {
        }

        protected virtual void OnDisposed(object sender, ChannelDisposedEventArgs e)
        {
        }

        protected virtual void OnError(object sender, ChannelErrorEventArgs e)
        {
        }

        protected virtual void OnOpening()
        {
        }

        protected virtual void OnReceive(object sender, ChannelReceiveEventArgs e)
        {
        }

        protected virtual void OnServerError(object sender, TcpServerErrorArgs e)
        {
        }

        public void Open(int port)
        {
            this.Open(new IPEndPoint(IPAddress.Any, port));
        }

        public void Open(IPEndPoint ep)
        {
            this._field_a = new TcpServer();
            this.OnBindEvent(this._field_a);
            this._field_a.Error += new EventTcpServerError(this.OnServerError);
            this._field_a.Open(ep);
            this.OnOpening();
        }

        public void Open(IPAddress ip, int port)
        {
            this.Open(new IPEndPoint(ip, port));
        }

        public void Open(string ip, int port)
        {
            this.Open(IPAddress.Parse(ip), port);
        }

        public TcpServer Server
        {
            get
            {
                return this._field_a;
            }
        }
    }
}

